package com.chinawayltd.ews.sample.app;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chinawayltd.ews.sample.core.exception.BusinessException;
import com.chinawayltd.ews.sample.manager.openApi.CustomOpenApiManager;
import com.chinawayltd.ews.sample.manager.redis.impl.DriverManagerRedisImpl;
import com.chinawayltd.ews.sample.model.TDriver;
import com.chinawayltd.ews.sample.model.TOrderDetail;
import com.chinawayltd.ews.sample.model.TTask;
import com.chinawayltd.ews.sample.model.TTaskNode;
import com.chinawayltd.ews.sample.model.task.TaskDetailVO;
import com.chinawayltd.ews.sample.model.task.TaskListVO;
import com.chinawayltd.ews.sample.model.task.TaskMaterielVO;
import com.chinawayltd.ews.sample.model.task.TaskNodeVO;
import com.chinawayltd.ews.sample.model.task.TaskOrderNodeListVO;
import com.chinawayltd.ews.sample.model.task.TaskOrderNodeVO;
import com.chinawayltd.ews.sample.model.task.TaskVO;
import com.chinawayltd.ews.sample.service.algorithm.DriverService;
import com.chinawayltd.ews.sample.service.order.OrderService;
import com.chinawayltd.ews.sample.service.task.TaskNodeService;
import com.chinawayltd.ews.sample.service.task.TaskService;
import com.chinawayltd.ews.sample.util.BaseController;
import com.chinawayltd.ews.sample.util.ResultModel;
import com.chinawayltd.ews.sample.util.StringUtils;
import com.chinawayltd.ews.sample.web.query.AppGirdQuery;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * @program: greeProject
 * @description 运输任务管理
 * @author: chenxin
 * @create: 2018年4月17日 下午7:41:00
 */
@Api(tags = { "App任务调用接口" })
@RestController
@RequestMapping(value = "/app/task")
public class AppTaskController extends BaseController{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private TaskService taskService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private TaskNodeService taskNodeService;
    @Autowired
    private CustomOpenApiManager customOpenApiManager;
    @Autowired
    private DriverService driverService;
    @Autowired
    private DriverManagerRedisImpl driverManagerRedisImpl;
    
	@Value("${sys.url}")
	private String sysUrl;
    private final String DRIVER = "DRIVER:";
    @ApiOperation(value = "运输任务信息列表查询接口(未完成的任务)")
    @RequestMapping(value = "/loadNoCompleteData", method = { RequestMethod.POST })
    public ResultModel loadNoCompleteData(AppGirdQuery queryParam, HttpServletRequest request) {
        ResultModel model = new ResultModel();
        try {
        	String token = request.getHeader("token");
        	logger.info("未完成的任务token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	Long driverId = null;//获取司机id
        	if(StringUtils.isBlank(driverStr)){//如果缓存没有
        		driverId = updateTokenAndGetDriverId(token, keyToken);
        	}else{
        		driverId = getDrtiverIdByToken(keyToken, driverStr, driverId);
        	}
        	List<TaskListVO> list = null;
        	String sortStr = queryParam.getSortStr();
        	if(StringUtils.isBlank(sortStr)){
        		queryParam.setSortStr("executState DESC");
        	}
        	if(driverId !=null){
        		queryParam.setDriverId(driverId.toString());
                list = taskService.applistTaskByPage(queryParam);
        	}else{
        		list = new ArrayList<>();
        	}
            model.setData(new JSONObject().fluentPut("result", list));
            model.setPage(queryParam);
        } catch (BusinessException e){
            model.setData(new JSONObject().fluentPut("result", new ArrayList<>()));
        } catch (Exception e){
            logger.error("运输任务列表查询出错！", e);
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", "查询失败!"));
            model.setSub_msg(e.getMessage());
        }
        return model;
    }

    
    @ApiOperation(value = "运输任务信息列表查询接口(完成的任务)")
    @RequestMapping(value = "/loadCompleteData", method = { RequestMethod.POST })
    public ResultModel loadCompleteData(AppGirdQuery queryParam, HttpServletRequest request) {
        ResultModel model = new ResultModel();
        try {
        	String token = request.getHeader("token");
        	logger.info("完成的任务token:"+token);
        	String keyToken = DRIVER+token;
        	logger.info("keyToken:"+keyToken);
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("driverStr:"+driverStr);
        	Long driverId = null;//获取司机id
        	if(StringUtils.isNotBlank(driverStr)){
        		Map map = (Map)JSON.parse(driverStr);
        		if(map!=null && !map.isEmpty() && map.get("phone") !=null){
        			String phone = map.get("phone").toString();
        			driverId = getDriverByPhone(phone);
        		}else{
        			throw new BusinessException("司机不存在！");
        		}
            	List<TaskListVO> list = null;
            	String sortStr = queryParam.getSortStr();
            	if(StringUtils.isBlank(sortStr)){
            		queryParam.setSortStr("finishTime DESC");
            	}
            	if(driverId !=null){
            		queryParam.setDriverId(driverId.toString());
                    list = taskService.applistCompleteTaskByPage(queryParam);
            	}else{
            		list = new ArrayList<>();
            	}
                model.setData(new JSONObject().fluentPut("result", list));
                model.setPage(queryParam);
        	}else{
				model.setData(new JSONObject().fluentPut("result", new ArrayList<>()));
        	}
        } catch (BusinessException e){
            model.setData(new JSONObject().fluentPut("result", new ArrayList<>()));
        } catch (Exception e){
            logger.error("运输任务列表查询出错！", e);
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", "查询失败!"));
            model.setSub_msg(e.getMessage());
        }
        return model;
    }
    
    @ApiOperation(value = "任务确认")
    @RequestMapping(value = "/confirm/{taskId}", method = { RequestMethod.GET })
    @ApiImplicitParam(paramType = "path", name = "taskId", value = "运输任务ID", dataType = "Long", required = true)
    public ResultModel confirmTaskBytaskId(@PathVariable Long taskId, HttpServletRequest request) {
    	ResultModel model = new ResultModel();
        try {
        	String token = request.getHeader("token");
        	logger.info("任务确认token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("任务确认driverStr:"+driverStr);
        	if(StringUtils.isNotBlank(driverStr)){
        		// 任务确认
            	taskService.confirmTaskBytaskId(taskId);
            	model.setData(new JSONObject().fluentPut("result", "确认成功"));
        	}else{
        		model.setSub_code(1);
                model.setData(new JSONObject().fluentPut("sub_msg", "您没有访问权限！"));
        	}
        }catch (BusinessException e){
            logger.info("任务确认信息失败：", e);
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
            model.setSub_msg(e.getMessage());
        }catch (Exception e){
        	logger.error("任务确认信息异常！id：" + taskId, e);
        	model.setSub_code(1);
        	model.setData(new JSONObject().fluentPut("sub_msg", "操作失败!"));
            model.setSub_msg(e.getMessage());
        }
		return model;
    }
    
    @ApiOperation(value = "开始任务(将任务改为执行中状态)")
    @RequestMapping(value = "/start/{taskId}", method = { RequestMethod.GET })
    @ApiImplicitParam(paramType = "path", name = "taskId", value = "运输任务ID", dataType = "Long", required = true)
    public ResultModel startTaskBytaskId(@PathVariable Long taskId, HttpServletRequest request) {
    	ResultModel model = new ResultModel();
        try {
        	String token = request.getHeader("token");
        	logger.info("开始任务token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("开始任务driverStr:"+driverStr);
        	if(StringUtils.isNotBlank(driverStr)){
            	TTask task = taskService.getTaskById(taskId);
        		if(task.getConfirmState() !=1){
        			model.setSub_code(1);
        			model.setData(new JSONObject().fluentPut("sub_msg", "任务未确认，请先确认"));
        		}else if(task.getExecutState() >0){
        			model.setSub_code(1);
        			model.setData(new JSONObject().fluentPut("sub_msg", "任务已经开始！"));
        		}else{
        			Date date = new Date();
            		//任务执行中
            		int result = taskService.updateExecutStateByTaskIdAndStatus(1, taskId, date);
        			if(result >0){
        				taskNodeService.completeTaskNodeByTaskIdAndNodeType(0, taskId, date);
        				//添加实际开始时间
        				taskService.updateActualStartByTaskId(taskId, date);
        				// 订单关联的订单的执行状态改为执行中
        				orderService.updateOrderGenerateStatus(2, taskId, date);//多余
        				orderService.updateOrderExecutStateByTaskId(1, taskId, date);
        				model.setData(new JSONObject().fluentPut("result", "开始任务成功"));
        			}else{
        				model.setSub_code(1);
            			model.setData(new JSONObject().fluentPut("sub_msg" , "开始任务失败"));
        			}
        		}
        	}else{
        		model.setSub_code(401);
                model.setData(new JSONObject().fluentPut("sub_msg", "您没有访问权限！"));
        	}
        }catch (BusinessException e){
            logger.info("开始任务信息失败：", e);
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
            model.setSub_msg(e.getMessage());
        }catch (Exception e){
			model.setData(new JSONObject().fluentPut("sub_msg" , "开始任务失败"));
			model.setSub_code(ResultModel.SUB_CODE_SYSTEM_ERROR);
            model.setSub_msg(e.getMessage());
        	logger.error("任务确认信息出错！id：" + taskId, e);
        }
		return model;
    }
    
    @ApiOperation(value = "根据任务ID查询当前任务节点")
    @RequestMapping(value = "/getTaskDetailByTaskId/{taskId}", method = { RequestMethod.GET })
    @ApiImplicitParam(paramType = "path", name = "taskId", value = "运输任务ID", dataType = "Long", required = true)
    public ResultModel getTaskDetailByTaskId(@PathVariable Long taskId, HttpServletRequest request) {
    	ResultModel model = new ResultModel();
		try {
			String token = request.getHeader("token");
			logger.info("任务节点token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("任务节点driverStr:"+driverStr);
        	Long driverId = null;
        	if(StringUtils.isBlank(driverStr)){
        		driverId = updateTokenAndGetDriverId(token, keyToken);//更新token
        	}else{
        		driverId = getDrtiverIdByToken(keyToken, driverStr, driverId);
        	}
        	TaskVO task = taskService.getTaskVOByTaskId(taskId);
        	if(task.getExecutState() ==0){
        		throw new BusinessException("任务未执行，无法进行下一步操作！");
        	}
        	// 2、查询任务节点列表，装卸货节点区别
        	List<TaskNodeVO> nodeList = taskNodeService.getTaskNodeList(taskId);
        	for (TaskNodeVO taskNodeVO : nodeList) {
				if(taskNodeVO.getNodeType() ==20 || taskNodeVO.getNodeType() ==21){
					//根据节点id查询装卸货节点对应的货物明细
					List<TaskMaterielVO> list = taskNodeService.getTaskMaterielListByNodeId(taskNodeVO.getId());
					taskNodeVO.setGoods(list);
					if(taskNodeVO.getNodeType() ==21){//卸货节点所有订单所有电梯口
						Map<String, Object> map = taskNodeService.getNodeTotalLiftByNodeId(taskNodeVO.getId());
						if(map !=null && !map.isEmpty()){
							String string = map.get("totalLift").toString();
							if(StringUtils.isNoneBlank(string)){
								taskNodeVO.setTotalLift(string.trim());//卸货节点所有订单所有电梯口
							}
						}
					}
				}
			}
        	TaskDetailVO taskDetail = new TaskDetailVO();
        	taskDetail.setTaskVO(task);
        	taskDetail.setNodeList(nodeList);
        	model.setData(new JSONObject().fluentPut("result", taskDetail));
        } catch (BusinessException e){
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
        } catch (Exception e){
        	model.setData(new JSONObject().fluentPut("sub_msg" , "查询异常"));
			model.setSub_code(ResultModel.SUB_CODE_SYSTEM_ERROR);
            model.setSub_msg(e.getMessage());
        	logger.error("根据任务ID查询当前任务节点！id：" + taskId, e);
        }
        return model;
    }
    
    @ApiOperation(value = "执行节点（出发、到达、装货、卸货等动作状态更变）")
    @RequestMapping(value = "/node/execute/{nodeId}", method = { RequestMethod.GET })
    @ApiImplicitParam(paramType = "path", name = "nodeId", value = "任务节点ID", dataType = "Long", required = true)
    public ResultModel executeTaskNode(@PathVariable Long nodeId, HttpServletRequest request) {
    	ResultModel model = new ResultModel();
    	int result = 0;
    	Date date = new Date();
        try {
        	String token = request.getHeader("token");
        	logger.info("执行节点token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("执行节点driverStr:"+driverStr);
        	if(StringUtils.isNotBlank(driverStr)){
        		// 1查询任务节点对象
        		TTaskNode node = taskNodeService.getById(nodeId);
        		// 2判断此节点序号前的节点执行状态，如果存在未完成执行的节点则提示先执行
        		List<TTaskNode> nodeList = taskNodeService.getBeforeNode(node);
        		if(nodeList.size() >0){
        			if(node.getNodeType().intValue() !=20 && node.getNodeType().intValue() !=21){
        				throw new BusinessException("前面的步骤还没有执行完毕");
        			}else{
        				List<TaskOrderNodeVO> nodeVO = getOrderAndDetailByNodeId(nodeId);
        				model.setData(new JSONObject().fluentPut("result", nodeVO));
        				return model;
        			}
        		}
        		// 3判断当前节点状态
        		if(node.getExecutState() ==2){
        			if(node.getNodeType().intValue() !=20 && node.getNodeType().intValue() !=21){
        				throw new BusinessException("此步骤已经执行完成！");
        			}else{
        				List<TaskOrderNodeVO> nodeVO = getOrderAndDetailByNodeId(nodeId);
        				model.setData(new JSONObject().fluentPut("result", nodeVO));
        				return model;
        			}
        		}else if(node.getExecutState() ==1){
        			if(node.getNodeType().intValue() !=20 && node.getNodeType().intValue() !=21){
        				throw new BusinessException("前面的步骤还没有执行完毕");//不存在
        			}else{
        				List<TaskOrderNodeVO> nodeVO = getOrderAndDetailByNodeId(nodeId);
        				model.setData(new JSONObject().fluentPut("result", nodeVO));
        				return model;
        			}
        		}else{//未开始的节点
        			if(node.getNodeType() ==0){//任务开始类型
        				result = taskNodeService.completeTaskNodeByNodeIdAndStatus(2, node.getId(), date);
						taskNodeService.updateNodeActualFinishTimeByNodeId(node.getId(), date);
        			}else if(node.getNodeType() ==1){//任务结束类型
        				// 判断当前任务所有节点是否都已完成,空表示此任务除去最终的一个完成类型外的节点都已完成
        				result = completeTask(result, date, node);
        			}else if(node.getNodeType() ==10){//出发类型
        				result = taskNodeService.completeTaskNodeByNodeIdAndStatus(2, node.getId(), date);
        				taskNodeService.updateNodeActualFinishTimeByNodeId(nodeId, date);
        			}else if(node.getNodeType() ==11){//到达类型
        				result = taskNodeService.completeTaskNodeByNodeIdAndStatus(2, node.getId(), date);
        				taskNodeService.updateNodeActualFinishTimeByNodeId(nodeId, date);
        			}else if(node.getNodeType() ==20){//装货类型
        				taskNodeService.updateTaskNodeByNodeIdAndStatus(1, nodeId, date);
        				//修改装卸货开始时间 TODO
        				taskNodeService.updateNodeExTendByNodeId(nodeId, date);
        				List<TaskOrderNodeVO> nodeVO = getOrderAndDetailByNodeId(nodeId);
        				model.setData(new JSONObject().fluentPut("result", nodeVO));
        				return model;
        			}else if(node.getNodeType() ==21){//卸货类型
        				taskNodeService.updateTaskNodeByNodeIdAndStatus(1, nodeId, date);
        				//修改装卸货开始时间 TODO
        				taskNodeService.updateNodeExTendByNodeId(nodeId, date);
        				List<TaskOrderNodeVO> nodeVO = getOrderAndDetailByNodeId(nodeId);
        				model.setData(new JSONObject().fluentPut("result", nodeVO));
        				return model;
        			}
        		}
        		if(result >0){
        			model.setData(new JSONObject().fluentPut("result", "执行成功！"));
        		}else{
        			model.setSub_code(1);
        			model.setData(new JSONObject().fluentPut("sub_msg", "执行失败！"));
        		}
        	}else{
        		model.setSub_code(1);
                model.setData(new JSONObject().fluentPut("sub_msg", "您没有访问权限！"));
        	}
        } catch (BusinessException e){
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
        } catch (Exception e){
        	model.setSub_code(1);
        	model.setData(new JSONObject().fluentPut("sub_msg", "执行失败！"));
        	model.setSub_msg(e.getMessage());
        	logger.error("任务执行节点失败！nodeId：" + nodeId, e);
        }
		return model;
    }

	private int completeTask(int result, Date date, TTaskNode node) throws Exception {
		Long taskId = node.getTaskId();
		List<TTaskNode> list = taskNodeService.getNoFinishNode(taskId);
		if(list.size() <=0){
			//修改完成结点
			result = taskNodeService.completeTaskNodeByNodeIdAndStatus(2, node.getId(), date);
			if(result >0){
				//节点实际完成时间
				taskNodeService.updateNodeActualFinishTimeByNodeId(node.getId(), date);
				//修改任务执行状态
				taskService.updateExecutStateByTaskIdAndStatus(2, taskId, date);
				//添加任务实际完成时间
				taskService.updateActualFinishByTaskId(taskId, date);
				//修改订单状态
				orderService.updateOrderExecutStateByTaskId(2, taskId, date);
			}
		}
		return result;
	}

	private List<TaskOrderNodeVO> getOrderAndDetailByNodeId(Long nodeId) throws Exception {
		List<TaskOrderNodeVO> nodeVO = taskNodeService.getNodeOrderByNodeId(nodeId);
		for (TaskOrderNodeVO taskOrderNodeVO : nodeVO) {
			List<TaskMaterielVO> list = taskNodeService.getTaskMaterielListByNodeIdAndOrderId(nodeId, taskOrderNodeVO.getId());
			taskOrderNodeVO.setGoods(list);
		}
		return nodeVO;
	}
    
	@ApiOperation(value = "确认装货接口（将对应的货物明细的实装数量修改确认，并将装货节点状态改为已完成）")
	@RequestMapping(value = "/updateTaskNodeAndMateriel", method = { RequestMethod.POST })
	public ResultModel updateTaskNodeAndMateriel(@RequestBody TaskOrderNodeListVO vo, HttpServletRequest request) {
		ResultModel model = new ResultModel();
		Date date = new Date();
		try {
			String token = request.getHeader("token");
			logger.info("确认装货接口token:"+token);
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	logger.info("确认装货接口driverStr:"+driverStr);
        	if(StringUtils.isNotBlank(driverStr)){
        		List<TaskOrderNodeVO> list = vo.getList();
    			if(list.size() <=0){
    				throw new BusinessException("货物明细不能为空，操作失败!");
    			}
    			Long nodeId = list.get(0).getNodeId();
            	completeShipment(list, nodeId);//装货
    			int result = completeTaskNodeAndUpdateFinishStatus(date, nodeId);
    			if(result > 0){
    				model.setData(new JSONObject().fluentPut("result", "装货成功!"));
    	        }else{
    	        	model.setSub_code(1);
                    model.setData(new JSONObject().fluentPut("sub_msg", "装货失败!"));
    	        }
        	}else{
        		model.setSub_code(1);
                model.setData(new JSONObject().fluentPut("sub_msg", "您没有访问权限!"));
        	}
        } catch (BusinessException e){
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
        } catch (Exception e){
        	model.setSub_code(1);
        	model.setData(new JSONObject().fluentPut("sub_msg", "装货失败!"));
        	model.setSub_msg(e.getMessage());
        	logger.error("确认装货接口失败!", e);
        }
		return model;
	}

	/**
	 * 装货
	 * @author: chenxin
	 * @date: 2018年7月5日 下午2:29:26
	 * @param list
	 * @param nodeId
	 * @throws Exception
	 * @throws BusinessException
	 */
	private void completeShipment(List<TaskOrderNodeVO> list, Long nodeId) throws Exception, BusinessException {
		TTaskNode taskNode = taskNodeService.getById(nodeId);
		// 如果不是装货或者卸货节点，操作失败
		if((taskNode.getNodeType().intValue() !=20) && (taskNode.getNodeType().intValue() !=21)){
			throw new BusinessException("该节点不是装卸货点，操作失败!");
		}
		// 如果已装货或者已卸货
		if(taskNode.getExecutState() ==2){
			throw new BusinessException("该装货点已完成装货!");
		}
		for (TaskOrderNodeVO taskOrderNodeVO : list) {
			List<TaskMaterielVO> goods = taskOrderNodeVO.getGoods();
			for (TaskMaterielVO taskMaterielVO : goods) {
				TOrderDetail od = new TOrderDetail();
				od.setId(taskMaterielVO.getOrderDetailId());
				od.setPlanNumber(taskMaterielVO.getPlanNumber());
				od.setActualNumber(taskMaterielVO.getActualNumber());
				orderService.updateOrderDetail(od);
			}
		}
	}

	/**
	 * 修改装货和卸货的节点状态和实际完成时间
	 * @author: chenxin
	 * @date: 2018年7月5日 下午2:20:22
	 * @param date
	 * @param nodeId
	 * @return
	 * @throws Exception
	 */
	private int completeTaskNodeAndUpdateFinishStatus(Date date, Long nodeId) throws Exception {
		int result = taskNodeService.completeTaskNodeByNodeIdAndStatus(2, nodeId, date);
		if(result > 0){
			//节点实际完成时间
			taskNodeService.updateNodeActualFinishTimeByNodeId(nodeId, date);
			//修改装卸货完成时间 TODO
			taskNodeService.completeNodeExTendByNodeId(nodeId, date);
		}
		return result;
	}
	
	@ApiOperation(value = "确认卸货接口（将卸货节点状态改为已完成）")
    @RequestMapping(value = "/updateOutturnNode/{nodeId}", method = { RequestMethod.GET })
    @ApiImplicitParam(paramType = "path", name = "nodeId", value = "节点ID", dataType = "Long", required = true)
    public ResultModel updateOutturnNode(@PathVariable Long nodeId, HttpServletRequest request) {
		ResultModel model = new ResultModel();
		Date date = new Date();
		try {
			String token = request.getHeader("token");
        	String keyToken = DRIVER+token;
        	String driverStr = driverManagerRedisImpl.getTokenDriverByKey(keyToken);
        	if(StringUtils.isNotBlank(driverStr)){
        		TTaskNode taskNode = taskNodeService.getById(nodeId);
            	// 如果不是卸货节点，操作失败
            	if(taskNode.getNodeType().intValue() !=21){
            		throw new BusinessException("该节点不是卸货点，操作失败!");
            	}
            	// 如果已卸货// 不会有这一步
            	if(taskNode.getExecutState() ==2){
            		throw new BusinessException("该卸货点已完成卸货!");
            	}
            	int result = completeTaskNodeAndUpdateFinishStatus(date, nodeId);
    			if(result > 0){
    				model.setData(new JSONObject().fluentPut("result" , "卸货成功"));
    	        }else{
    	        	model.setSub_code(1);
                    model.setData(new JSONObject().fluentPut("sub_msg", "卸货失败"));
    	        }
        	}else{
        		model.setSub_code(1);
                model.setData(new JSONObject().fluentPut("sub_msg", "您没有访问权限！"));
        	}
        } catch (BusinessException e){
            model.setSub_code(1);
            model.setData(new JSONObject().fluentPut("sub_msg", e.getMessage()));
        } catch (Exception e){
        	model.setSub_code(1);
        	model.setData(new JSONObject().fluentPut("sub_msg", "卸货失败!"));
        	model.setSub_msg(e.getMessage());
        	logger.error("确认卸货接口失败!", e);
        }
		return model;
	}
	
	
	private Long getDrtiverIdByToken(String keyToken, String driverStr, Long driverId)
			throws Exception, BusinessException {
		Map map = (Map)JSON.parse(driverStr);
		if(map!=null && !map.isEmpty() && map.get("phone") !=null){
			String string = map.get("phone").toString();
			driverId = getDriverByPhone(string);
			String keyPhone = DRIVER+string;
			String driverToken = driverManagerRedisImpl.getTokenDriverByKey(keyPhone);
			if(!keyToken.equals(driverToken)){
				updateTokenDriver(keyToken, keyPhone, driverStr, driverToken);//更新tokenDriver
			}
		}else{
			throw new BusinessException("司机不存在！");
		}
		return driverId;
	}

	private Long updateTokenAndGetDriverId(String token, String keyToken) throws IOException, Exception {
		String phone = getPhoneByApi(token);//根据token通过api获取phone
		Long driverId = getDriverByPhone(phone);
		Map<String, String> map = new HashMap<String, String>();
		map.put("phone", phone);
		map.put("id", driverId.toString());
		String jsonString = JSON.toJSONString(map);
		String keyPhone = DRIVER+phone;
		String driverToken = driverManagerRedisImpl.getTokenDriverByKey(keyPhone);
		if(StringUtils.isNotBlank(driverToken)){
			if(!keyToken.equals(driverToken)){
				updateTokenDriver(keyToken, keyPhone, jsonString, driverToken);
			}
		}else{
			setDriverToken(keyToken, jsonString, keyPhone);
		}
		return driverId;
	}

	private void setDriverToken(String keyToken, String jsonString, String keyPhone) throws Exception {
		driverManagerRedisImpl.setTokenDriver(keyToken, jsonString);
		driverManagerRedisImpl.setTokenDriver(keyPhone, keyToken);
	}

    /**
     * 通过司机手机查询司机id
     * @author: chenxin
     * @date: 2018年7月5日 下午12:15:40
     * @param phone
     * @return
     * @throws Exception
     */
	private Long getDriverByPhone(String phone) throws Exception {
		Long driverId = null;
		List<TDriver> driver = driverService.getDriverByPhone(phone);
		if(driver !=null && driver.size() >0){//如果有司机
			TDriver tDriver = driver.get(0);
			driverId = tDriver.getId();
		}else{
			throw new BusinessException("司机不存在！");
		}
		return driverId;
	}

	private String getPhoneByApi(String token) throws IOException {
		JSONObject jsonObject = customOpenApiManager.appDriverInfo(sysUrl, token);
		if(jsonObject ==null){
			throw new BusinessException("根据token查询api的司机失败！");
		}
		JSONObject object = jsonObject.getJSONObject("data");
		if(object ==null){
			throw new BusinessException("根据token查询api的司机为空！");
		}
		if(object.getString("mobile") ==null){
			throw new BusinessException("根据token查询api的司机为空！");
		}
		return object.getString("mobile");
	}

	private void updateTokenDriver(String keyToken, String keyPhone, String jsonString, String driverToken)
			throws Exception {
		driverManagerRedisImpl.deleteTokenDriver(driverToken);
		setDriverToken(keyToken, jsonString, keyPhone);
	}
    
}
